package ua.org.mtgatherer.deckloaders;

import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.text.SimpleDateFormat;
import java.util.*;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import ua.org.mtgatherer.entities.CardPlace;
import ua.org.mtgatherer.entities.DeckCard;
import ua.org.mtgatherer.entities.DeckType;
import ua.org.mtgatherer.entities.TcgPlayerDeck;

public class TcgPlayerDeckLoader {
   
   private final static String DECKURL = "http://magic.tcgplayer.com/db/deck_print.asp?deck_id=";
   private final static String CARDURL = "http://sales.starcitygames.com//cardsearch.php?singlesearch=";
   private static int START_POSITION_OF_DECK_NUMBER_IN_URL = 30;
   private static int END_POSITION_OF_DECK_NUMBER_IN_URL = 36;
   
   public static List<String> getFirstPlaceDecksNumbers(String fromDate, String toDate) throws IOException {
      List<String> decks = new ArrayList<String>();
      
      final String actualUrl =
              "http://magic.tcgplayer.com/db/deck_search_result.asp?Format=Type%20II&place=1st&DateRange1="
              + fromDate + "&DateRange2=" + toDate;
      
      final Document decksPage = Jsoup.connect(actualUrl).get();
      
      final Elements links = decksPage.select("a");
      
      for (Element link : links) {
         final String linkString = link.toString();
         
         if (!linkString.contains("target") && linkString.contains("/db/deck.asp?")) {
            decks.add(linkString.substring(START_POSITION_OF_DECK_NUMBER_IN_URL, END_POSITION_OF_DECK_NUMBER_IN_URL));
         }
      }
      
      return decks;
   }
   
   public static TcgPlayerDeck getDeckByNumber(String deckNumber) throws IOException {
      
      TcgPlayerDeck tcgPlayerDeck = new TcgPlayerDeck();
      
      Document doc = Jsoup.connect(DECKURL + deckNumber).get();
      
      Element deckElement = doc.getElementsByTag("div").first();
      
      List<String> rawDeckList = Arrays.asList(deckElement.toString().split("<br />"));
      
      List<String> cleanDeckList = new LinkedList<String>();
      
      for (String deckLine : rawDeckList) {
         deckLine = removeTags(deckLine);
         deckLine.trim();
         if (!deckLine.trim().isEmpty()) {
            cleanDeckList.add(deckLine);
         }
      }
      
      tcgPlayerDeck.setDeckNumber(deckNumber);
      
      tcgPlayerDeck.setTitle(cleanDeckList.get(0));
      cleanDeckList.remove(0);
      
      tcgPlayerDeck.setOwner(cleanDeckList.get(0));
      cleanDeckList.remove(0);
      
      System.out.println(tcgPlayerDeck.getOwner());
      
      try {
         tcgPlayerDeck.setDeckTypeOnAddDate(DeckType.valueOf(cleanDeckList.get(0).toUpperCase().replaceAll(" ", "")));
      } catch (IllegalArgumentException e) {
         System.out.println("Unknown deck format");
      }
      
      cleanDeckList.remove(0);
      
      List<DeckCard> deckCardList = tcgPlayerDeck.getDeck().getDeckList();
      
      CardPlace cardPlace = CardPlace.MAINDECK;
      
      for (String deckLine : cleanDeckList) {
         if (deckLine.equals("Sideboard:")) {
            cardPlace = CardPlace.SIDEBOARD;
         }
         
         short cardAmount = getCardAmount(deckLine);
         
         if (cardAmount != 0) {
            deckCardList.add(new DeckCard(cardAmount, getCardName(deckLine), cardPlace));
         }
      }
      
      System.out.println(tcgPlayerDeck);
      return tcgPlayerDeck;
   }
   
   public static List<String> getLastDayFirstPlaceDecksNumbers() throws IOException {
      return getFirstPlaceDecksNumbers(getPreviousDayDate(), getCurrentDate());
   }
   
   public static List<String> getCardPriceByCardName(String name) throws IOException, URISyntaxException {
      List<String> prices = new ArrayList();
      URI uri = new URI(
              "http",
              "sales.starcitygames.com",
              "/cardsearch.php",
              "singlesearch=" + name,
              null);
      final String actualUrl = uri.toURL().toString();
      final Document cardPage = Jsoup.connect(actualUrl).get();
      Elements elements = cardPage.getElementsByTag("b");
      
      for (Element element : elements) {
         String price = element.toString();
         if (price.contains("$")) {
            prices.add(price.substring(4, price.indexOf("/") - 1));
         }
      }
      return prices;
   }
   
   public static String removeTags(String htmlString) {
      return Jsoup.parse(htmlString).text();
   }
   
   public static short getCardAmount(String deckString) {
      String[] cardString = deckString.split(" ");
      
      try {
         return Short.valueOf(cardString[0]);
      } catch (NumberFormatException e) {
         return 0;
      }
   }
   
   public static String getCurrentDate() {
      return new SimpleDateFormat("M/d/y").format(new Date());
   }
   
   public static String getPreviousDayDate() {
      Calendar calendar = Calendar.getInstance();
      calendar.add(Calendar.DAY_OF_MONTH, -1);
      return new SimpleDateFormat("M/d/y").format(calendar.getTime());
   }
   
   public static String getCardName(String deckString) {
      String[] cardString = deckString.split(" ");
      
      String cardName = "";
      
      for (int i = 1; i < cardString.length; i++) {
         cardName += cardString[i] + " ";
      }
      
      return cardName.trim();
   }
}
